#include <Arduino.h>
#include <U8g2lib.h>
#include <math.h>

#define PIN_U   18
#define PIN_D   21

U8G2_SSD1309_128X64_NONAME0_F_4W_HW_SPI u8g2(U8G2_R0, /* cs=*/ 12, /* dc=*/ 4, /* reset=*/ 6);  

typedef struct {
    byte val;
    byte last_val;
} KEY_T;

typedef struct {
    byte id;
    byte press;
    byte update_flag;
    byte res;
} KEY_MSG;

typedef struct {
    char *str;
    byte len;
} SETTING_LIST;

SETTING_LIST list[] = {
    {"list", 4},
    {"ab", 2},
    {"abc", 3},
    {"abcd", 4},
};

short x, x_trg;  // x 当前位置数值， x_trg 目标坐标值
short y = 19, y_trg = 18;

short frame_len, frame_len_trg; // 框的宽度
short frame_y, frame_y_trg;     // 框的y

char ui_select = 0;

int state;
KEY_T key[2] = {0};
KEY_MSG key_msg = {0};

byte get_io_val(byte ch) {
    if (ch == 0) {
        return digitalRead(PIN_U);
    } else {
        return digitalRead(PIN_D);
    }
}

void key_init(void) {
    for (int i = 0; i < 2; i++) {
        key[i].val = key[i].last_val = get_io_val(i);
    }
}

void key_scan(void) {
    for (int i=0; i<2; i++) {
        key[i].val = get_io_val(i);
        if (key[i].val != key[i].last_val) {
            key[i].last_val = key[i].val;
            if (key[i].val == 0) {
                key_msg.id = i;
                key_msg.press = 1;
                key_msg.update_flag = 1;
            }
        }
    }
}

int ui_run(short *a, short *a_trg, u8 step, u8 slow_cnt) {
    u8 temp;

    temp = abs(*a_trg - *a) > slow_cnt ? step : 1;
    if (*a < *a_trg) {
        *a += temp;
    }
    else if (*a > *a_trg) {
        *a -= temp;
    } else {return 0;}
    return 1;
}

void setup(void)
{
    //u8g2.begin();
    //u8g2.setFont(u8g2_font_8x13_tf);
    //u8g2.drawStr(2,13, "hello.");
    //u8g2.sendBuffer();
    
    pinMode(PIN_U, INPUT_PULLUP);
    pinMode(PIN_D, INPUT_PULLUP);
    key_init();
    u8g2.begin();
    u8g2.setFont(u8g2_font_t0_22_mf);
    frame_len = frame_len_trg = list[ui_select].len *13;
}

void ui_show(void) {
    int list_len = sizeof(list) / sizeof(SETTING_LIST);
    u8g2.clearBuffer();
    for (int i=0; i<list_len; i++) {
        u8g2.drawStr(x+2, y+i*20, list[i].str);
    }
    u8g2.drawRFrame(x, frame_y, frame_len, 22, 3);
    ui_run(&frame_y, &frame_y_trg, 5, 4);
    ui_run(&frame_len, &frame_len_trg, 10, 5);
    u8g2.sendBuffer();
}

void ui_proc(void) {
    int list_len = sizeof(list) / sizeof(SETTING_LIST);

    if (key_msg.update_flag && key_msg.press) {
        key_msg.update_flag = 0;
        if (key_msg.id) {
            ui_select++;
            if (ui_select >= list_len) {
                ui_select = list_len - 1;
            }
        }
        else {
            ui_select--;
            if(ui_select < 0) {
                ui_select = 0;
            }
        }
        frame_y_trg = ui_select *20;
        frame_len_trg = list[ui_select].len *13;
    }
    ui_show();
}

void loop(void)
{
    key_scan();
    ui_proc();
}